package com.extsci.webmail.web.controller;

import cc.ccoke.validate.annotation.ParamVerify;
import cc.ccoke.validate.type.VerifyType;
import com.extsci.webmail.common.entity.http.*;
import com.extsci.webmail.common.entity.http.ResponseStatus;
import com.extsci.webmail.common.entity.mail.Mail;
import com.extsci.webmail.common.entity.sensitive.Sensitive;
import com.extsci.webmail.common.type.FieldType;
import com.extsci.webmail.common.type.MailBoxType;
import com.extsci.webmail.common.type.SortType;
import com.extsci.webmail.web.service.MailService;
import com.extsci.webmail.web.service.SensitiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 邮件
 * @author ccoke
 */
@RestController
public class MailController {
    private final MailService mailService;
    private final SensitiveService sensitiveService;

    @Autowired
    public MailController(MailService mailService, SensitiveService sensitiveService) {
        this.mailService = mailService;
        this.sensitiveService = sensitiveService;
    }

    /**
     * 发送邮件/保存到草稿箱
     */
    @PostMapping
    public ObjectRestResponse postMail(@RequestBody Mail mail) {
        boolean isDraft = mail.getIsDraft() != null && mail.getIsDraft();
        return isDraft ? mailService.save(mail) : mailService.send(mail);
    }


    /**
     * 删除邮件（移动到回收站或彻底删除）
     */
    @DeleteMapping("/{type}")
    @ParamVerify(type = VerifyType.INCLUDE, value = {"mailList", "mailList.uids", "mailList.isDelete"})
    public ObjectRestResponse<String> deleteMails(@PathVariable("type")String type, @RequestBody MailListRequest mailList) {
        return mailService.remove(MailBoxType.getType(type), mailList);
    }


    /**
     * 从邮箱获取指定id邮件信息
     */
    @GetMapping("/{type}/mail")
    @ParamVerify
    public ObjectRestResponse<Mail> getMailById(@PathVariable("type")String type, @RequestParam("uid")Long uid) {
        MailBoxType mailBoxType = MailBoxType.getType(type);
        return mailService.getMailByUid(mailBoxType, uid);
    }

    /**
     * 设置指定邮箱中邮件是否已读
     */
    @PutMapping("/{type}/isseen")
    @ParamVerify(type = VerifyType.INCLUDE, value = {"mailList", "mailList.uids", "mailList.isSeen"})
    public ObjectRestResponse<String> setIsSeen(@PathVariable("type")String type, @RequestBody MailListRequest mailList) {
        return mailService.setIsSeen(MailBoxType.getType(type), mailList);
    }

    /**
     * 标记指定邮箱所有邮件已读
     */
    @PutMapping("/{type}/isseen/all")
    public ObjectRestResponse<String> setAllIsSeen(@PathVariable("type")String type) {
        return mailService.setAllIsSeen(MailBoxType.getType(type));
    }

    /**
     * 清空回收站
     */
    @DeleteMapping("/trash/all")
    public ObjectRestResponse<String> deleteMailsFromTrash(){
        return mailService.makeTrashEmpty();
    }

    /**
     * 移动邮件到目标目录
     */
    @PutMapping("/{srcType}/to/{targetType}")
    @ParamVerify(type = VerifyType.INCLUDE, value = {"mailList","mailList.uids"})
    public ObjectRestResponse<String>  putMailsFolder(@PathVariable("srcType")String srcType, @PathVariable("targetType")String targetType, @RequestBody MailListRequest mailList) {
        return mailService.move(MailBoxType.getType(srcType), MailBoxType.getType(targetType), mailList);
    }

    /**
     * 获取邮箱配额
     */
    @GetMapping("/mailbox/quota")
    public ObjectRestResponse<MailBoxResponse> getMailBoxQuota(){
        return mailService.getMailBoxQuota();
    }

    /**
     * 获取邮箱内邮件数量
     * 收件箱为未读邮件数量
     * 其他邮箱为所有邮件数量
     */
    @GetMapping("/mailbox/counts")
    public ObjectRestResponse<Map<String, Integer>> getCountInMailBox(){
        return mailService.getCountInMailBox();
    }

    /**
     * 获取指定邮箱邮件列表
     * @param type 邮箱类型 inbox draft spam sent trash
     * @param currentPage 当前页码，从第0页开始
     * @param pageSize 一页显示数目
     * @param keyword 按关键字搜索
     * @param fieldType 排序关键字
     * @param sortType ASC 升序/ DESC 降序
     */
    @GetMapping("/{type}")
    @ParamVerify(type = VerifyType.INCLUDE, value = {"type", "currentPage", "pageSize"})
    public ObjectRestResponse<MailResponse> getMailBox(
            @PathVariable("type")String type,
            @RequestParam("currentPage")Integer currentPage,
            @RequestParam("pageSize")Integer pageSize,
            @RequestParam(value = "keyword",required = false) String keyword,
            @RequestParam(value = "field", required = false) String fieldType,
            @RequestParam(value = "sort", required = false) String sortType) {
        return mailService.getMailBox(MailBoxType.getType(type), currentPage, pageSize, keyword, FieldType.getType(fieldType), SortType.getType(sortType));
    }

    /**
     * 根据发件人、主题、发件日期获取收件箱内邮件id
     */
    @PostMapping("/uid")
    @ParamVerify(type = VerifyType.INCLUDE, value = {"mail", "mail.senderUser", "mail.subject", "mail.sendTimeStamp"})
    public ObjectRestResponse<String> getMailUidFromInbox(@RequestBody Mail mail) {
        return mailService.getMailUidFromInbox(mail);
    }




    /**
     * 获取敏感词列表
     */
    @GetMapping("/sensitive")
    @ParamVerify(type = VerifyType.IGNORE, value = {"keyword"})
    public ObjectRestResponse<Pageable<Sensitive>> getSensitive(@RequestParam("currentPage")Integer currentPage, @RequestParam("pageSize")Integer pageSize, @RequestParam(required = false) String keyword){
        return new ObjectRestResponse<>(ResponseStatus.SUCCESS, sensitiveService.getSensitives(currentPage, pageSize, keyword));
    }

    /**
     * 添加敏感词
     */
    @PostMapping("/sensitive")
    @ParamVerify(type = VerifyType.IGNORE, value = {"sensitive.uuid", "sensitive.createAt"})
    public ObjectRestResponse<Sensitive> postSensitive(@RequestBody Sensitive sensitive){
        return sensitiveService.addSensitive(sensitive);
    }


    /**
     * 修改敏感词
     */
    @PutMapping("/sensitive")
    @ParamVerify(type = VerifyType.IGNORE, value = {"sensitive.createAt"})
    public ObjectRestResponse<Sensitive> putSensitive(@RequestBody Sensitive sensitive){
        return sensitiveService.modifySensitive(sensitive);
    }

    /**
     * 删除敏感词
     */
    @DeleteMapping("/sensitive")
    @ParamVerify
    public ObjectRestResponse<String> deleteSensitive(@RequestBody List<String> uuids){
        return sensitiveService.removeSensitives(uuids);
    }
}
